home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / utility / sysgraf4.zip / SOURCE.ZIP / SYSGRAPH.C next >
C/C++ Source or Header  |  1991-08-15  |  39KB  |  1,569 lines

  1. /*
  2.   * System Graph - Version 4.00 (June 6, 1991.)
  3.   * By James Straub
  4.   *
  5.   * For a history of this program please refer to the documentaion.
  6.   *
  7.   *
  8.   *
  9.   * Programmer notes:
  10.   *
  11.   *    This program is written for Borland C++.
  12.   *
  13.   *     "#pragma argsused" tells the compiler not to be
  14.   *    alarmed if I don't use a variable that was created.
  15.   *
  16.   * Please feel free to modify this program.
  17.   *
  18.   *
  19.   *
  20.   * NOTE:  It's now August and I have finally decided to send this out...
  21.   *        Now with more experience in Windows programing under my belt
  22.   *        I realize that this baby could use some improvementa. Some day
  23.   *        I hope to get around to it.  Have fun with it...
  24.   *
  25. */
  26.  
  27. /************************************************************************
  28. * Files to include.
  29. */
  30. #include <windows.h>
  31. #include "sysgraph.h"
  32.  
  33.  
  34. /************************************************************************
  35. * Global data structure.
  36. */
  37. typedef struct {
  38.     HANDLE hInstance;        // The instance of this program
  39.     HWND   hWnd;            // ID of the program's window
  40.     char   name[NAME_SIZE];        // name of program
  41.     BOOL   halt;            // Halts graph when in a dialog box
  42. } Program_Data;
  43.  
  44. typedef struct {
  45.     POINT table[MAX_POINTS_ALL];    // Holds graph points
  46.     int   msg_count;        // # of messages since timer
  47.     int   apex;            // Highest point on graph
  48. } Graph_Data;
  49.  
  50. typedef struct {
  51.     short int graph_type;        // Type of graph.
  52.     short int update_time;        // Time to update graph
  53.     BOOL      on_top;        // Keep graph on top
  54.     BOOL      on_caption;        // Keep graph on active caption
  55.     BOOL      auto_rescale;        // Automatically rescale graph
  56.     BOOL      iconic;        // Window is iconic
  57.     RECT      window_position;    // Graph's position on desktop
  58. } Program_State;
  59.  
  60.  
  61. /************************************************************************
  62. * Global declarations.
  63. */
  64. Program_Data  prog;
  65. Graph_Data    graph;
  66. Program_State state;
  67. BOOL          popup_mode = TRUE;
  68.  
  69.  
  70. /************************************************************************
  71. * This initializes the first instance of the program by setting up the
  72. * window class and registering it.
  73. *
  74. * INPUT:  hInstance = This is the instance of this program.
  75. *
  76. * OUTPUT: NONE
  77. */
  78. BOOL InitFirst(HANDLE hInstance)
  79. {
  80.     WNDCLASS WndClass;
  81.  
  82.     /*
  83.      * Define the window class.
  84.      */
  85.     WndClass.style         = CS_VREDRAW | CS_HREDRAW;
  86.     WndClass.lpfnWndProc   = MainProc;
  87.     WndClass.cbClsExtra    = 0;
  88.     WndClass.cbWndExtra    = 0;
  89.     WndClass.hInstance     = hInstance;
  90.     WndClass.hIcon         = (HICON)  NULL;
  91.     WndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  92.     WndClass.hbrBackground = (HBRUSH) NULL;
  93.     WndClass.lpszMenuName  = (LPSTR)  NULL;
  94.     WndClass.lpszClassName = (LPSTR)  prog.name;
  95.  
  96.     /*
  97.      * Register the window class.
  98.      */
  99.     if ( RegisterClass(&WndClass) == 0)
  100.         return(FALSE);
  101.  
  102.     return(TRUE);
  103.  
  104. } /* InitFirst */
  105.  
  106.  
  107. /************************************************************************
  108. * This initializes all the global vars in this program.  This includes
  109. * clearing the graph table.
  110. *
  111. * INPUT:  hInstance = This is the instance of this program.
  112. *       hWnd      = This is a handle to the window just created.
  113. *
  114. * OUTPUT: NONE
  115. */
  116. void InitGlobals(HANDLE hInstance, HWND hWnd)
  117. {
  118.     int count;
  119.  
  120.     /*
  121.      * Initialize the global
  122.      * variables.
  123.      */
  124.     prog.hWnd       = hWnd;
  125.     prog.hInstance  = hInstance;
  126.     prog.halt       = FALSE;
  127.     graph.msg_count = 0;
  128.     graph.apex      = 0;
  129.  
  130.     /*
  131.      * Initialize the graph table.
  132.      */
  133.     for (count = 0; count < MAX_POINTS; count++)
  134.     {
  135.         graph.table[count].x = count;
  136.         graph.table[count].y = 0;
  137.     }
  138.     graph.table[MAX_POINTS].x   = LAST_POINT;
  139.     graph.table[MAX_POINTS+1].x = 0;
  140.  
  141. } /* InitGlobals */
  142.  
  143.  
  144. /************************************************************************
  145. * This is where we initialize each and every instance of this program.
  146. *
  147. * INPUT:  hInstance     = This is the instance of this program.
  148. *      hPrevInstance = This is the instance of the previous program.
  149. *
  150. * OUTPUT: NONE
  151. */
  152. #pragma argsused
  153. BOOL WinInit(HANDLE hInstance,   HANDLE hPrevInstance,
  154.          LPSTR  lpszCmdLine, int    cmdShow)
  155. {
  156.     HWND hWnd;
  157.  
  158.     /*
  159.      * Load the program name from the string
  160.      * table. If it could not find the string
  161.      * load a default string name.
  162.      */
  163.     if (LoadString(hInstance, IDS_NAME, (LPSTR)prog.name, NAME_SIZE) == 0)
  164.         strcpy(prog.name,"No name found!");
  165.  
  166.     /*
  167.      * Set the WINCLASS of the window only
  168.      * if this is the first instance of the
  169.      * program.
  170.      */
  171.     if (! hPrevInstance)
  172.     {
  173.         if (InitFirst(hInstance) == FALSE)
  174.             return(FALSE);
  175.     }
  176.  
  177.     /*
  178.      * Create the window for the program.
  179.      */
  180.      hWnd = CreateWindow((LPSTR) prog.name,
  181.                  (LPSTR) prog.name,
  182.                  WS_POPUP,
  183.                  DEF_WIN_LEFT,
  184.                  DEF_WIN_TOP,
  185.                  (DEF_WIN_RIGHT  - DEF_WIN_LEFT),
  186.                  (DEF_WIN_BOTTOM - DEF_WIN_TOP),
  187.                  (HWND)  NULL,
  188.                  (HMENU) NULL,
  189.                  hInstance,
  190.                  (LPSTR) NULL);
  191.  
  192.     /*
  193.      * Make sure the window was
  194.      * created.
  195.      */
  196.     if (! hWnd)
  197.         return(FALSE);
  198.  
  199.     /*
  200.      * Initialize all global vars.
  201.      */
  202.     InitGlobals(hInstance, hWnd);
  203.  
  204.     /*
  205.      * Update the window but don't
  206.      * show it yet.
  207.      */
  208.     ShowWindow(hWnd, SW_HIDE);
  209.     UpdateWindow(hWnd);
  210.  
  211.     return(TRUE);
  212.  
  213. } /* WinInit */
  214.  
  215.  
  216. /************************************************************************
  217. * This function gets the setup information from the win.ini file.  If
  218. * the user never saved his/her setup then use the defaults.
  219. *
  220. * INPUT:  NONE.
  221. *
  222. * OUTPUT: NONE
  223. */
  224. void GetProgramSetup()
  225. {
  226.     SetCursor(LoadCursor(NULL, IDC_WAIT));
  227.  
  228.     state.graph_type             = GetProfileInt((LPSTR) INI_NAME,
  229.                          (LPSTR) GRAPH_TYPE_KEY,
  230.                          DEF_GRAPH_TYPE);
  231.  
  232.     state.auto_rescale           = GetProfileInt((LPSTR) INI_NAME,
  233.                          (LPSTR) AUTO_RESCALE_KEY,
  234.                          DEF_AUTO_RESCALE);
  235.  
  236.     state.update_time            = GetProfileInt((LPSTR) INI_NAME,
  237.                                              (LPSTR) UPDATE_TIME_KEY,
  238.                          DEF_UPDATE_TIME);
  239.  
  240.     state.on_top                 = GetProfileInt((LPSTR) INI_NAME,
  241.                          (LPSTR) ON_TOP_KEY,
  242.                          DEF_ON_TOP);
  243.  
  244.         state.on_caption             = GetProfileInt((LPSTR) INI_NAME,
  245.                                              (LPSTR) ON_CAPTION_KEY,
  246.                          DEF_ON_CAPTION);
  247.  
  248.     state.iconic                 = GetProfileInt((LPSTR) INI_NAME,
  249.                                              (LPSTR) ICONIC_KEY,
  250.                          DEF_ICONIC);
  251.  
  252.     state.window_position.left   = GetProfileInt((LPSTR) INI_NAME,
  253.                                              (LPSTR) WIN_LEFT_KEY,
  254.                          DEF_WIN_LEFT);
  255.  
  256.     state.window_position.right  = GetProfileInt((LPSTR) INI_NAME,
  257.                                              (LPSTR) WIN_RIGHT_KEY,
  258.                          DEF_WIN_RIGHT);
  259.  
  260.     state.window_position.top    = GetProfileInt((LPSTR) INI_NAME,
  261.                                              (LPSTR) WIN_TOP_KEY,
  262.                          DEF_WIN_TOP);
  263.  
  264.     state.window_position.bottom = GetProfileInt((LPSTR) INI_NAME,
  265.                          (LPSTR) WIN_BOTTOM_KEY,
  266.                          DEF_WIN_BOTTOM);
  267.  
  268.     SetCursor(LoadCursor(NULL, IDC_ARROW));
  269.  
  270. } /* GetProgramSetup */
  271.  
  272.  
  273. /************************************************************************
  274. * This function saves the setup to the win.ini file.
  275. *
  276. * INPUT:  NONE.
  277. *
  278. * OUTPUT: NONE
  279. */
  280. void SetProgramSetup()
  281. {
  282.     char dummy[10];        // Temporary storage for number
  283.  
  284.     /*
  285.      * Show the wait cursor.
  286.      */
  287.     SetCursor(LoadCursor(NULL, IDC_WAIT));
  288.  
  289.     sprintf(dummy, "%1.2f", VERSION_NUMBER);
  290.     WriteProfileString((LPSTR) INI_NAME,
  291.             (LPSTR) VERSION_KEY,
  292.             (LPSTR) dummy);
  293.  
  294.     sprintf(dummy, "%d", state.graph_type);
  295.     WriteProfileString((LPSTR) INI_NAME,
  296.             (LPSTR) GRAPH_TYPE_KEY,
  297.             (LPSTR) dummy);
  298.  
  299.     sprintf(dummy, "%d", state.auto_rescale);
  300.     WriteProfileString((LPSTR) INI_NAME,
  301.             (LPSTR) AUTO_RESCALE_KEY,
  302.             (LPSTR) dummy);
  303.  
  304.     sprintf(dummy, "%d", state.update_time);
  305.     WriteProfileString((LPSTR) INI_NAME,
  306.             (LPSTR) UPDATE_TIME_KEY,
  307.             (LPSTR) dummy);
  308.  
  309.     sprintf(dummy, "%d", state.on_top);
  310.     WriteProfileString((LPSTR) INI_NAME,
  311.             (LPSTR) ON_TOP_KEY,
  312.             (LPSTR) dummy);
  313.  
  314.     sprintf(dummy, "%d", state.on_caption);
  315.     WriteProfileString((LPSTR) INI_NAME,
  316.             (LPSTR) ON_CAPTION_KEY,
  317.             (LPSTR) dummy);
  318.  
  319.         sprintf(dummy, "%d", state.iconic);
  320.     WriteProfileString((LPSTR) INI_NAME,
  321.             (LPSTR) ICONIC_KEY,
  322.             (LPSTR) dummy);
  323.  
  324.     sprintf(dummy, "%d", state.window_position.left);
  325.     WriteProfileString((LPSTR) INI_NAME,
  326.             (LPSTR) WIN_LEFT_KEY,
  327.             (LPSTR) dummy);
  328.  
  329.     sprintf(dummy, "%d", state.window_position.right);
  330.     WriteProfileString((LPSTR) INI_NAME,
  331.             (LPSTR) WIN_RIGHT_KEY,
  332.             (LPSTR) dummy);
  333.  
  334.     sprintf(dummy, "%d", state.window_position.top);
  335.     WriteProfileString((LPSTR) INI_NAME,
  336.             (LPSTR) WIN_TOP_KEY,
  337.             (LPSTR) dummy);
  338.  
  339.     sprintf(dummy, "%d", state.window_position.bottom);
  340.     WriteProfileString((LPSTR) INI_NAME,
  341.             (LPSTR) WIN_BOTTOM_KEY,
  342.             (LPSTR) dummy);
  343.  
  344.     /*
  345.      * Show the arrow cursor.
  346.      */
  347.     SetCursor(LoadCursor(NULL, IDC_ARROW));
  348.  
  349. } /* SetProgramSetup */
  350.  
  351.  
  352. /************************************************************************
  353. * After reading the win.ini file we must put our settings to work.
  354. * This includes setting the timer and showing the window.
  355. *
  356. * INPUT:  NONE.
  357. *
  358. * OUTPUT: NONE
  359. */
  360. BOOL DoSetup()
  361. {
  362.     /*
  363.      * Set the timer to its default
  364.      * value and were done!
  365.      */
  366.     if (! SetProgramTimer(state.update_time - 9))
  367.         return(FALSE);
  368.  
  369.     /*
  370.      * Position the window where the
  371.      * user wants it.
  372.      */
  373.     SetWindowPos(prog.hWnd, 1,
  374.              state.window_position.left,
  375.              state.window_position.top,
  376.              (state.window_position.right -
  377.               state.window_position.left),
  378.              (state.window_position.bottom -
  379.              state.window_position.top),
  380.              SWP_NOZORDER);
  381.  
  382.     /*
  383.      * Show the window the
  384.      * way the user wants it.
  385.      */
  386.     if (state.iconic)
  387.         ShowWindow(prog.hWnd, SW_SHOWMINIMIZED);
  388.     else
  389.         ShowWindow(prog.hWnd, SW_SHOWNORMAL);
  390.  
  391.     return(TRUE);
  392.  
  393. } /* DoSetup */
  394.  
  395.  
  396. /************************************************************************
  397. * This function is the main entry point for this Windows application.
  398. *
  399. * INPUT:  hInstance     = This is the instance of this program.
  400. *      hPrevInstance = This is the instance of the previous program.
  401. *
  402. * OUTPUT: TRUE of FALSE depending if initialization went well.
  403. *
  404. */
  405. #pragma argsused
  406. int PASCAL WinMain(HANDLE hInstance,   HANDLE hPrevInstance,
  407.            LPSTR  lpszCmdLine, int    nCmdShow)
  408. {
  409.     MSG Msg;    // holds windows message structure.
  410.  
  411.     /*
  412.      * Initialize the Window and all
  413.      * the program data!
  414.      */
  415.     if (! WinInit(hInstance, hPrevInstance, lpszCmdLine, nCmdShow))
  416.         return(FALSE);
  417.  
  418.     /*
  419.      * Get the settings from the
  420.      * win.ini file if they are there.
  421.      */
  422.     GetProgramSetup();
  423.  
  424.     /*
  425.      * This sets up the program the
  426.      * way the user wants it.
  427.      */
  428.     if (! DoSetup())
  429.         return(FALSE);
  430.  
  431.     /*
  432.      * Main loop for the program.  While
  433.      * looping I count the number of times
  434.      * this loop was iterated.
  435.      */
  436.     while ( THE_SKY_IS_BLUE ) {
  437.         graph.msg_count++;
  438.  
  439.         if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
  440.         {
  441.             if (Msg.message == WM_QUIT)
  442.                 break;
  443.  
  444.             TranslateMessage(&Msg);
  445.             DispatchMessage(&Msg);
  446.         }
  447.      }
  448.  
  449.     return(TRUE);
  450.  
  451. } /* WinMain */
  452.  
  453.  
  454. /************************************************************************
  455. * This tells Windows to send a timer message at a certain time from now.
  456. *
  457. * INPUT:   time_in_sec = The time in seconds that the timer will be set to.
  458. *
  459. * RETURNS: TRUE or FALSE depending if it worked or not
  460. *
  461. */
  462. BOOL SetProgramTimer( int time_in_sec )
  463. {
  464.     /*
  465.      * Kill the old timer and
  466.      * start a new one.
  467.      */
  468.     KillTimer(prog.hWnd, 1);
  469.     if (SetTimer(prog.hWnd, 1, time_in_sec*1000, NULL) == 0)
  470.         return(FALSE);
  471.  
  472.     return(TRUE);
  473.  
  474. } /* SetProgramTimer */
  475.  
  476.  
  477. /************************************************************************
  478. * This function is passed a value of which it puts on the graph table.
  479. * While doing this I find the peek of all the points.  Since this
  480. * graph is a representation of polygon, we must update the last two
  481. * points of the table in order to "close" the polygon.
  482. *
  483. * INPUT:  new_point = The new point to append to the graph.
  484. *
  485. * OUTPUT: NONE
  486. *
  487. */
  488. void AddPoint( int new_point )
  489. {
  490.     register int index;           // Used to increment graph
  491.  
  492.     /*
  493.      * If in auto rescale mode then
  494.      * clear the peek.
  495.      */
  496.     if (state.auto_rescale)
  497.         graph.apex = 0;
  498.  
  499.     /*
  500.      * Move all points down one and update
  501.      * the peek value.
  502.      */
  503.     for (index = 0; index < LAST_POINT; index++) {
  504.         graph.table[index].y = graph.table[index+1].y;
  505.         graph.apex = max(graph.apex, graph.table[index].y);
  506.     }
  507.     graph.table[LAST_POINT].y = new_point;
  508.  
  509.     /*
  510.      * If the new point is larger
  511.      * than the peek make it the peek!
  512.      */
  513.     graph.apex = max(graph.apex, new_point);
  514.  
  515.     /*
  516.      * This creates the last vertices
  517.      * to "close" the polygon of points.
  518.      */
  519.     graph.table[LAST_POINT+1].y = graph.apex;
  520.     graph.table[LAST_POINT+2].y = graph.apex;
  521.  
  522. } /* AddPoint */
  523.  
  524.  
  525. /************************************************************************
  526. * This function rescales the graph by updating the peek value.
  527. *
  528. * INPUT:  NONE
  529. *
  530. * OUTPUT: NONE
  531. *
  532. */
  533. void RescaleGraph()
  534. {
  535.     int index;
  536.  
  537.     graph.apex = 0;
  538.     for (index = 0; index < MAX_POINTS; index++)
  539.         graph.apex = max(graph.apex, graph.table[index].y);
  540.  
  541. } /* RescaleGraph */
  542.  
  543.  
  544. /************************************************************************
  545. * This changes the window from a popup to its normal state and back.
  546. * This is used to be able to move and size the window.
  547. *
  548. * INPUT:  NONE
  549. *
  550. * OUTPUT: NONE
  551. *
  552. */
  553. void ChangeWinStyle()
  554. {
  555.     RECT   window_rect;        // Our window's size and position
  556.     static BOOL on_cap_status;    // Holds the on_caption status
  557.  
  558.     popup_mode = ! popup_mode;
  559.  
  560.     /*
  561.      * If popup_mode is true then make
  562.      * the window a popup window.
  563.      */
  564.     if (popup_mode)
  565.     {
  566.         SetWindowLong(prog.hWnd, GWL_STYLE, WS_POPUP);
  567.         state.on_caption = on_cap_status;
  568.     }
  569.     else
  570.     {
  571.         SetWindowLong(prog.hWnd, GWL_STYLE, STANDARD_STYLE);
  572.         on_cap_status = state.on_caption;
  573.         state.on_caption = FALSE;
  574.     }
  575.  
  576.     /*
  577.      * This is a way of making windows
  578.      * aware of the change done to the
  579.      * window.
  580.      */
  581.     GetWindowRect(prog.hWnd, &window_rect);
  582.     MoveWindow(prog.hWnd, window_rect.left, window_rect.top,
  583.                  window_rect.right  - window_rect.left,
  584.                  window_rect.bottom - window_rect.top,
  585.                  TRUE);
  586.     ShowWindow(prog.hWnd, SW_SHOW);
  587.  
  588. } /* ChangeWinStyle */
  589.  
  590.  
  591. /************************************************************************
  592. * This function moves our window on the caption bar of the currently
  593. * active parent window.
  594. *
  595. * INPUT:  NONE
  596. *
  597. * OUTPUT: NONE
  598. *
  599. */
  600. void MoveToTopWindowCap()
  601. {
  602.     static RECT oldrect;    // The rect of the last positioning
  603.     HWND   hWndAct;        // The active windows handle
  604.     HWND   hWndPAct;    // The parent window of the active one
  605.     RECT   rect;        // The current active window's rect
  606.     LONG   act_win_style;    // The active windows style
  607.  
  608.     /*
  609.      * If we are minimized
  610.      * then do nothing.
  611.      */
  612.     if (IsIconic(prog.hWnd))
  613.         return;
  614.  
  615.     /*
  616.      * Get the active window handle
  617.      * and make sure its the parent.
  618.      */
  619.     hWndAct = GetActiveWindow();
  620.     if ((hWndPAct = GetParent(hWndAct)) != NULL)
  621.         hWndAct = hWndPAct;
  622.  
  623.     /*
  624.      * If the host window has not changed
  625.      * size or position then do nothing.
  626.      */
  627.     GetWindowRect(hWndAct, &rect);
  628.     if (EqualRect(&rect,&oldrect))
  629.     {
  630.         /*
  631.          * Only show the window if it's
  632.          * blocked.
  633.          */
  634.         if (GetWindow(prog.hWnd,GW_HWNDFIRST) != prog.hWnd)
  635.             ShowWindow(prog.hWnd, SW_SHOWNA);
  636.         return;
  637.     }
  638.     else
  639.         oldrect = rect;
  640.  
  641.     /*
  642.      * Show the graph in it's normal poisition
  643.      * if there is no window to place it on or if
  644.      * the active window is hidden or if the
  645.      * active window is iconic.
  646.      */
  647.     if ( (hWndAct == prog.hWnd)       ||
  648.          (! IsWindowVisible(hWndAct)) ||
  649.            (IsIconic(hWndAct))           )
  650.     {
  651.         SetWindowPos(prog.hWnd, NULL,
  652.                  state.window_position.left,
  653.                  state.window_position.top,
  654.                  (state.window_position.right -
  655.                   state.window_position.left),
  656.                  (state.window_position.bottom -
  657.                  state.window_position.top),
  658.                  SWP_NOACTIVATE);
  659.         return;
  660.     }
  661.  
  662.     /*
  663.      * To position the graph on a window
  664.      * we must find the position in which
  665.      * to place it.  We do this by looking
  666.      * at the window style.
  667.      */
  668.     act_win_style = GetWindowLong(hWndAct, GWL_STYLE);
  669.     if (! (act_win_style & WS_CAPTION))
  670.         return;
  671.  
  672.     /*
  673.      * This following three "if"
  674.      * statements check to see
  675.      * what type of window the host is,
  676.      * in order to properly position
  677.      * the window.
  678.      */
  679.     if (act_win_style & WS_THICKFRAME)
  680.     {
  681.         SetWindowPos(prog.hWnd, NULL,
  682.                  rect.left                       +
  683.                  GetSystemMetrics(SM_CXDLGFRAME) +
  684.                  GetSystemMetrics(SM_CXBORDER)   +
  685.                  GetSystemMetrics(SM_CXSIZE),
  686.                  rect.top + GetSystemMetrics(SM_CYDLGFRAME),
  687.                  (3 * GetSystemMetrics(SM_CXSIZE)),
  688.                  GetSystemMetrics(SM_CYSIZE),
  689.                  SWP_NOACTIVATE);
  690.         return;
  691.  
  692.     }
  693.  
  694.     if (act_win_style & DS_MODALFRAME)
  695.     {
  696.         SetWindowPos(prog.hWnd, NULL,
  697.                  rect.left +               +
  698.                  GetSystemMetrics(SM_CXSIZE) +
  699.                  (2 * GetSystemMetrics(SM_CXBORDER)) + 5,
  700.                  rect.top + GetSystemMetrics(SM_CYBORDER) + 4,
  701.                  (3 * GetSystemMetrics(SM_CXSIZE)),
  702.                  GetSystemMetrics(SM_CYSIZE),
  703.                  SWP_NOACTIVATE);
  704.         return;
  705.     }
  706.  
  707.     if (act_win_style & WS_BORDER)
  708.     {
  709.         SetWindowPos(prog.hWnd, NULL,
  710.                  rect.left                   +
  711.                  GetSystemMetrics(SM_CXSIZE) +
  712.                  (2 * GetSystemMetrics(SM_CXBORDER)),
  713.                  rect.top + GetSystemMetrics(SM_CYBORDER),
  714.                  (3 * GetSystemMetrics(SM_CXSIZE)),
  715.                  GetSystemMetrics(SM_CYSIZE),
  716.                  SWP_NOACTIVATE);
  717.         return;
  718.     }
  719.  
  720. } /* MoveToTopWindowCap */
  721.  
  722.  
  723. /************************************************************************
  724. * This function gets run everytime this window receives a timer
  725. * message.
  726. *
  727. * INPUT:  NONE
  728. *
  729. * OUTPUT: NONE
  730. *
  731. */
  732. void DoTimmer(WORD wParam)
  733. {
  734.     /*
  735.      * If this is the timer for the
  736.      * menu then display it.
  737.      */
  738.     if (wParam == 2)
  739.     {
  740.         KillTimer(prog.hWnd, 2);
  741.         DialogBox(prog.hInstance, (LPSTR) "MENU_BOX",
  742.               prog.hWnd, MakeProcInstance(
  743.               (FARPROC) MenuDialog, prog.hInstance));
  744.         return;
  745.     }
  746.  
  747.  
  748.     /*
  749.      * If the system is halted then
  750.      * pause graph display.  It is
  751.      * halted when a dialog box is
  752.      * showing.
  753.      */
  754.     if (! prog.halt)
  755.     {
  756.         /*
  757.          * Add a point to the graph table.
  758.          */
  759.         AddPoint(graph.msg_count / (state.update_time - 9 ));
  760.  
  761.         /*
  762.          * Move the window on the caption
  763.          * of the host window if the user
  764.          * wants it that way. Otherwise
  765.          * if the user wants the graph on
  766.          * the top, put it there.
  767.          * NOTE: When on_caption is TRUE
  768.          * then on_top must be also!
  769.          */
  770.         if (state.on_caption)
  771.             MoveToTopWindowCap();
  772.         else
  773.         {
  774.             if (state.on_top)
  775.                 if (GetWindow(prog.hWnd,GW_HWNDFIRST) != prog.hWnd)
  776.                     ShowWindow(prog.hWnd, SW_SHOWNA);
  777.         }
  778.  
  779.         /*
  780.          * Invalidate the client rectangle
  781.          * to paint the graph
  782.          */
  783.         InvalidateRect(prog.hWnd, NULL, FALSE);
  784.     }
  785.  
  786.     /*
  787.      * Reset the message counter and
  788.      * start a new timer.
  789.      */
  790.     graph.msg_count = 0;
  791.     SetProgramTimer(state.update_time - 9);
  792.  
  793. } /* DoTimmer */
  794.  
  795.  
  796. /************************************************************************
  797. * This draws a 3D frame on the given rectangle 'rect' with a width of
  798. * 'frame_width'.  It returns a RECT that gives the coordinates for the
  799. * face of the button like structure.
  800. *
  801. * INPUT:  hdc         = The device context.
  802. *         rect        = The rectangle to put the frame in.
  803. *      frame_width = The width to make the frame.
  804. *
  805. * OUTPUT: temp_rect = A rectangle definition of the area inside the frame.
  806. */
  807. RECT Draw3DFrame(HDC hDC, RECT Rect, int frame_width)
  808. {
  809.     POINT frame[5];        // Points for the frame
  810.     int   in_value;        // Half the length of the smallest side
  811.     int   oldDC;        // Holds original DC
  812.     RECT  tmpRect;        // Stores the area inside the frame
  813.     HRGN  tmpRgn;        // Holds newly created region
  814.  
  815.     oldDC = SaveDC(hDC);
  816.  
  817.     /*
  818.      * Get a value that is half the
  819.      * length of the smallest side.
  820.      */
  821.     if (Rect.right-Rect.left < Rect.bottom-Rect.top)
  822.         in_value = (Rect.right - Rect.left) / 2;
  823.     else
  824.         in_value = (Rect.bottom - Rect.top) / 2;
  825.  
  826.     /*
  827.      * Build the polygon that will
  828.      * make the dark shaded sides
  829.      * of the 3d frame.
  830.      */
  831.     frame[0].x = Rect.right;
  832.     frame[0].y = Rect.top;
  833.     frame[1].x = Rect.right;
  834.     frame[1].y = Rect.bottom;
  835.     frame[2].x = Rect.left;
  836.     frame[2].y = Rect.bottom;
  837.     frame[3].x = Rect.left+in_value;
  838.     frame[3].y = Rect.bottom-in_value;
  839.     frame[4].x = Rect.right-in_value;
  840.     frame[4].y = Rect.top+in_value;
  841.  
  842.     /*
  843.      * Make sure the frame width
  844.      * is smaller then 'in_value'
  845.      */
  846.     frame_width = (frame_width > in_value) ? in_value : frame_width;
  847.  
  848.     /*
  849.      * This defines the face of
  850.      * the structure.
  851.      */
  852.     tmpRect         = Rect;
  853.     tmpRect.left   += frame_width;
  854.     tmpRect.top    += frame_width;
  855.     tmpRect.right  -= frame_width;
  856.     tmpRect.bottom -= frame_width;
  857.  
  858.     /*
  859.      * Draw the face of the
  860.      * button like structure.
  861.      */
  862.     tmpRgn = CreateRectRgn(tmpRect.left, tmpRect.top,
  863.                    tmpRect.right, tmpRect.bottom);
  864.     FillRgn(hDC, tmpRgn, GetStockObject(LTGRAY_BRUSH));
  865.     DeleteObject(tmpRgn);
  866.  
  867.     /*
  868.      * Don't paint over the face
  869.      * of the structure that was
  870.      * just painted.
  871.      */
  872.     ExcludeClipRect(hDC, tmpRect.left, tmpRect.top,
  873.                  tmpRect.right, tmpRect.bottom);
  874.  
  875.     /*
  876.      * Create and fill the rectangles
  877.      * of the high lighted and darkened
  878.      * areas of the button like structure.
  879.      */
  880.     tmpRgn = CreateRectRgn(Rect.left, Rect.top, Rect.right, Rect.bottom);
  881.     FillRgn(hDC, tmpRgn, GetStockObject(WHITE_BRUSH));
  882.     DeleteObject(tmpRgn);
  883.     tmpRgn = CreatePolygonRgn(frame, 5, WINDING);
  884.     FillRgn(hDC, tmpRgn, GetStockObject(GRAY_BRUSH));
  885.     DeleteObject(tmpRgn);
  886.  
  887.     RestoreDC(hDC,oldDC);
  888.  
  889.     /*
  890.      * Return the face rectangle.
  891.      */
  892.     return(tmpRect);
  893.  
  894. } /* Draw3DFrame */
  895.  
  896.  
  897. /************************************************************************
  898. * This function draws the graph of the system load.  It does this by
  899. * making a polygon out of its points.
  900. *
  901. * INPUT:  hDC  = The device context.
  902. *         Rect = The rectangle to put the frame in.
  903. *
  904. * OUTPUT: NONE
  905. */
  906. void PlotGraph(HDC hDC, RECT Rect)
  907. {
  908.     HANDLE tmpObj1;        // A prior object's handle
  909.     HANDLE tmpObj2;        // A prior object's handle
  910.     int    oldMap;        // Holds the past map mode
  911.     int    oldDC;        // Holds original DC
  912.  
  913.     oldDC = SaveDC(hDC);
  914.  
  915.     /*
  916.      * Set mapping mode.
  917.      */
  918.     oldMap = SetMapMode(hDC, MM_ANISOTROPIC);
  919.  
  920.     /*
  921.      * Invert the graph or keep it
  922.      * normal depending on the user's
  923.      * choice.
  924.      */
  925.     if (state.graph_type == IDSD_QUEUE)
  926.     {
  927.         SetWindowOrg(hDC, 0, 0);
  928.         SetWindowExt(hDC, MAX_POINTS - 1, graph.apex);
  929.         SetViewportOrg(hDC, Rect.left, Rect.top);
  930.         SetViewportExt(hDC, Rect.right-(2*Rect.left)+1,
  931.                 Rect.bottom-(2*Rect.top)+1);
  932.         tmpObj1 = SelectObject(hDC, GetStockObject(BLACK_PEN));
  933.         tmpObj2 = SelectObject(hDC, CreateSolidBrush(RGB_YELLOW));
  934.     }
  935.     else
  936.     {
  937.         SetWindowOrg(hDC, 0, 0);
  938.         SetWindowExt(hDC, MAX_POINTS - 1, -graph.apex);
  939.         SetViewportOrg(hDC, Rect.left, Rect.bottom-1);
  940.         SetViewportExt(hDC, Rect.right-(2*Rect.left)+1,
  941.                 Rect.bottom-(2*Rect.top)+1);
  942.         tmpObj1 = SelectObject(hDC, GetStockObject(BLACK_PEN));
  943.         tmpObj2 = SelectObject(hDC, CreateSolidBrush(RGB_BLUE));
  944.         graph.table[LAST_POINT+1].y = 0;
  945.         graph.table[LAST_POINT+2].y = 0;
  946.     }
  947.  
  948.     /*
  949.      * Draw the polygon.
  950.      */
  951.     Polygon(hDC, graph.table, MAX_POINTS_ALL);
  952.     DeleteObject(SelectObject(hDC, tmpObj2));
  953.     DeleteObject(SelectObject(hDC, tmpObj1));
  954.  
  955.     /*
  956.      * Adjust the last points
  957.      * back to where they were.
  958.      */
  959.     graph.table[LAST_POINT+1].y = graph.apex;
  960.     graph.table[LAST_POINT+2].y = graph.apex;
  961.  
  962.     /*
  963.      * Reset the the map mode.
  964.      */
  965.     SetMapMode(hDC, oldMap);
  966.  
  967.     RestoreDC(hDC, oldDC);
  968.  
  969. } /* PlotGraph */
  970.  
  971.  
  972. /************************************************************************
  973. * This function paints the system graph and its frame.
  974. *
  975. * INPUT:  hwnd  = This window's handle.
  976. *
  977. * OUTPUT: NONE
  978. *
  979. */
  980. void PaintGraph(HWND hwnd)
  981. {
  982.     PAINTSTRUCT ps;        // Paint structure of this function
  983.     RECT        Rect;    // The client rectangular coordinates
  984.     HDC         hDC;    // Handle to a display context
  985.     HBITMAP     buf_bitmap;    // Holds a bitmaped image of the output
  986.     HDC         buf_hDC;    // A memory device context equal to hdc
  987.     RECT        inside_rect;// A rectangular area of the inside frame
  988.  
  989.     /*
  990.      * Start painting session and
  991.      * get the client's rectangular
  992.      * coordinates.
  993.      */
  994.     hDC = BeginPaint(hwnd,&ps);
  995.     GetClientRect(hwnd,&Rect);
  996.  
  997.     /*
  998.      * Create a memory DC the same
  999.      * size as the updated rectangle
  1000.      * and copy it's image into it.
  1001.      */
  1002.     buf_hDC     = CreateCompatibleDC(hDC);
  1003.     buf_bitmap  = CreateCompatibleBitmap(hDC, Rect.right-Rect.left,
  1004.                          Rect.bottom-Rect.top);
  1005.     SelectObject(buf_hDC, buf_bitmap);
  1006.  
  1007.     /*
  1008.      * Draw the frame around the graph.
  1009.      *
  1010.      */
  1011.     inside_rect = Draw3DFrame(buf_hDC, Rect, DEF_FRAME_WIDTH);
  1012.  
  1013.     /*
  1014.      * Now draw the graph inside the
  1015.      * frame and copy that into the
  1016.      * dummy bitmap!
  1017.      */
  1018.     PlotGraph(buf_hDC, inside_rect);
  1019.  
  1020.     /*
  1021.      * Finally, copy the bitmap onto
  1022.      * the rectangle.
  1023.      */
  1024.     BitBlt(hDC, Rect.left, Rect.top, Rect.right-Rect.left,
  1025.            Rect.bottom-Rect.top,
  1026.            buf_hDC, 0, 0, SRCCOPY);
  1027.  
  1028.     /*
  1029.      * Delete the space taken up by
  1030.      * the two temporary work areas.
  1031.      */
  1032.     DeleteDC(buf_hDC);
  1033.     DeleteObject(buf_bitmap);
  1034.  
  1035.     EndPaint(hwnd, &ps);
  1036.  
  1037. } /* PaintGraph */
  1038.  
  1039.  
  1040. /************************************************************************
  1041. * This function enables a window to be sized smaller then normal.  We do
  1042. * this by changing what Windows thinks is the smallest it can size a
  1043. * window.
  1044. *
  1045. * INPUT:  lParam = is a long pointer to an array of 5 POINT
  1046. *                  data structures.
  1047. *
  1048. * OUTPUT: NONE
  1049. *
  1050. * NOTE: I tryed to make the size of the frame smaller but Windows didn't
  1051. *       seem to like that.  The sizes I picked seem to work fine.  If you
  1052. *    notice that when you size a window and the background of the
  1053. *    desktop "blackens" then make the size larger.
  1054. */
  1055. void SetMinSize(LONG lParam)
  1056. {
  1057.     LPPOINT rgpt = (LPPOINT) lParam;
  1058.  
  1059.     /*
  1060.      * Increment to the point
  1061.      * that contains the min
  1062.      * values.
  1063.      */
  1064.     rgpt++;    rgpt++;    rgpt++;
  1065.  
  1066.     rgpt->x = 3 * GetSystemMetrics(SM_CXSIZE);  // These values
  1067.     rgpt->y = GetSystemMetrics(SM_CYSIZE);      //  work fine.
  1068.  
  1069. } /* SetMinSize */
  1070.  
  1071.  
  1072. /************************************************************************
  1073. * This function is called by Windows when it sends me a message.
  1074. *
  1075. * INPUT: hWnd    = The window handle.
  1076. *     message = The message to look at.
  1077. *     wParam  = The parameter of the message.
  1078. *     lParam  = The parameter of the message.
  1079. *
  1080. * OUTPUT: NONE
  1081. *
  1082. *************************************************************************/
  1083. long FAR PASCAL MainProc (HWND hWnd,   unsigned message,
  1084.               WORD wParam, LONG     lParam)
  1085. {
  1086.     switch(message)
  1087.     {
  1088.     case WM_TIMER:        // Timer to get graph point or menu.
  1089.         DoTimmer(wParam);
  1090.         break;
  1091.  
  1092.     case WM_GETMINMAXINFO:    // Makes the window size smaller.
  1093.         SetMinSize(lParam);
  1094.         return(DefWindowProc(hWnd, message, wParam, lParam));
  1095.  
  1096.     case WM_PAINT:        // Paints the graph
  1097.         PaintGraph(hWnd);
  1098.         break;
  1099.  
  1100.     case WM_QUERYOPEN:    // Keeps track of when were maximized
  1101.         state.iconic = FALSE;
  1102.         return(DefWindowProc(hWnd, message, wParam, lParam));
  1103.  
  1104.     case WM_SIZE:        // Keeps track of when were minimized
  1105.         if (wParam == SIZEICONIC)
  1106.             state.iconic = TRUE;
  1107.         return(DefWindowProc(hWnd, message, wParam, lParam));
  1108.  
  1109.     case WM_NCCALCSIZE:    // Keeps track of the window size
  1110.         if ((! state.on_caption) && (! IsIconic(hWnd)))
  1111.             CopyRect(&state.window_position, (LPRECT) lParam);
  1112.         return(DefWindowProc(hWnd, message, wParam, lParam));
  1113.  
  1114.     case WM_MOVE:        // Kills the menu if the user moves the icon
  1115.         if (IsIconic(hWnd))
  1116.             KillTimer(hWnd, 2);
  1117.         return(DefWindowProc(hWnd, message, wParam, lParam));
  1118.  
  1119.     case WM_QUERYDRAGICON:    // Changes the cursor when dragging the icon
  1120.         return(LoadCursor(prog.hInstance, "ICON_CURSOR"));
  1121.  
  1122.     case WM_RBUTTONDOWN:    // Changes the window style to size it
  1123.         ChangeWinStyle();
  1124.         break;
  1125.  
  1126.     case WM_NCLBUTTONDOWN:    // Starts the menu timer
  1127.         if (IsIconic(hWnd))
  1128.             SetTimer(hWnd, 2, GetDoubleClickTime(), NULL);
  1129.         return(DefWindowProc(hWnd, message, wParam, lParam));
  1130.  
  1131.     case WM_NCLBUTTONDBLCLK:// Stops the menu from showing
  1132.         KillTimer(hWnd, 2);
  1133.         return(DefWindowProc(hWnd, message, wParam, lParam));
  1134.  
  1135.     case WM_SETCURSOR:    // Kills the dialog box
  1136.         if (prog.halt)
  1137.         {
  1138.             if ( (LOWORD(lParam) == (unsigned)HTERROR) &&
  1139.                  (HIWORD(lParam) == WM_LBUTTONDOWN) )
  1140.                 EndDialog(GetActiveWindow(), TRUE);
  1141.         }
  1142.         return(DefWindowProc(hWnd, message, wParam, lParam));
  1143.  
  1144.     case WM_LBUTTONDOWN:    // Allows moving of a whole window
  1145.         if (! IsIconic(hWnd))
  1146.         {
  1147.             if (! popup_mode)
  1148.             {
  1149.                 SetCursor(LoadCursor(NULL, IDC_SIZE));
  1150.                 return(DefWindowProc(hWnd, WM_NCLBUTTONDOWN,
  1151.                        HTCAPTION, lParam));
  1152.             }
  1153.             else
  1154.                 DialogBox(prog.hInstance, (LPSTR) "MENU_BOX",
  1155.                       hWnd, MakeProcInstance(
  1156.                       (FARPROC) MenuDialog, prog.hInstance));
  1157.         }
  1158.         return(DefWindowProc(hWnd, message, wParam, lParam));
  1159.  
  1160.     case WM_DESTROY:    // Kills all timers and leaves.
  1161.         KillTimer(hWnd, 1);
  1162.         KillTimer(hWnd, 2);
  1163.         PostQuitMessage(TRUE);
  1164.         break;
  1165.  
  1166.     default:
  1167.         return(DefWindowProc(hWnd, message, wParam, lParam));
  1168.     }
  1169.  
  1170.     return((long) 0);
  1171.  
  1172. } /* end MainProc */
  1173.  
  1174.  
  1175. /************************************************************************
  1176. * This function positions the menu dialog box where the mouse cursor is
  1177. * and if the program is iconic then positions it on the icon.
  1178. *
  1179. * INPUT:  NONE
  1180. *
  1181. * OUTPUT: NONE
  1182. */
  1183. void SetDlgPos(HWND hDlg)
  1184. {
  1185.     POINT Point;
  1186.     RECT  rect;
  1187.     int   iX, iY;
  1188.     RECT  windRect;
  1189.  
  1190.     GetWindowRect(hDlg, &rect);
  1191.  
  1192.     if (state.iconic)
  1193.     {
  1194.         GetWindowRect(prog.hWnd, &windRect);
  1195.         Point.x = windRect.left;
  1196.         Point.y = windRect.top;
  1197.         iX = Point.x + (rect.right  - rect.left);
  1198.         iY = Point.y + (rect.bottom - rect.top);
  1199.     }
  1200.     else
  1201.     {
  1202.         GetCursorPos(&Point);
  1203.         iX = Point.x + (rect.right  - rect.left);
  1204.         iY = Point.y + (rect.bottom - rect.top);
  1205.     }
  1206.  
  1207.  
  1208.     if ((iX > GetSystemMetrics(SM_CXSCREEN)) ||
  1209.         (iY > GetSystemMetrics(SM_CYSCREEN))   )
  1210.     {
  1211.         if ((iX > GetSystemMetrics(SM_CXSCREEN)) &&
  1212.             (iY > GetSystemMetrics(SM_CYSCREEN))   )
  1213.             SetWindowPos(hDlg, 1, Point.x + 3 - (rect.right-rect.left),
  1214.                     Point.y + 3 - (rect.bottom-rect.top),
  1215.                     0, 0, SWP_NOSIZE);
  1216.         else
  1217.         {
  1218.             if (iY > GetSystemMetrics(SM_CYSCREEN))
  1219.                 SetWindowPos(hDlg, 1, Point.x - 3,
  1220.                         Point.y + 3 - (rect.bottom-rect.top),
  1221.                         0, 0, SWP_NOSIZE);
  1222.             if (iX > GetSystemMetrics(SM_CXSCREEN))
  1223.                 SetWindowPos(hDlg, 1, Point.x + 3 - (rect.right-rect.left),
  1224.                         Point.y - 3,
  1225.                         0, 0, SWP_NOSIZE);
  1226.         }
  1227.     }
  1228.     else
  1229.         SetWindowPos(hDlg, 1, Point.x-3, Point.y-3, 0, 0, SWP_NOSIZE);
  1230.  
  1231. } /* SetDlgPos */
  1232.  
  1233.  
  1234. /************************************************************************
  1235. * This handles all the messages for the configuration dialog box.
  1236. *
  1237. * INPUT:  hDlg     = The dialog handle.
  1238. *      imessage = The message to look at.
  1239. *      wParam   = The parameter of the message.
  1240. *      lParam   = The parameter of the message.
  1241. *
  1242. * OUTPUT: NONE
  1243. */
  1244. #pragma argsused
  1245. BOOL FAR PASCAL SetupDialog( HWND hDlg,   unsigned imessage,
  1246.                  WORD wParam, LONG     lParam)
  1247. {
  1248.     static short update_rate;
  1249.     static short graph_type;
  1250.     static BOOL  auto_rescale;
  1251.     static BOOL  keep_on_top;
  1252.     static BOOL  follow_window;
  1253.  
  1254.     switch (imessage)
  1255.     {
  1256.     case WM_INITDIALOG:
  1257.         prog.halt = TRUE;
  1258.         follow_window  = state.on_caption;
  1259.         keep_on_top    = state.on_top;
  1260.         update_rate    = state.update_time;
  1261.         graph_type     = state.graph_type;
  1262.         auto_rescale   = state.auto_rescale;
  1263.  
  1264.         /*
  1265.          * Check the buttons to the
  1266.          * current setup.
  1267.          */
  1268.         CheckRadioButton(hDlg, IDSD_1SEC, IDSD_5SEC, update_rate);
  1269.         CheckRadioButton(hDlg, IDSD_QUEUE, IDSD_INV_QUEUE, graph_type);
  1270.         CheckDlgButton(hDlg, IDSD_AUTO_RESCALE, auto_rescale);
  1271.         CheckDlgButton(hDlg, IDSD_ON_TOP, keep_on_top);
  1272.         CheckDlgButton(hDlg, IDSD_ON_CAPTION, follow_window);
  1273.         return(FALSE);
  1274.  
  1275.     case WM_DESTROY:
  1276.         prog.halt = FALSE;
  1277.         break;
  1278.  
  1279.     case WM_ACTIVATEAPP:
  1280.         EndDialog(hDlg, TRUE);
  1281.         return(FALSE);
  1282.  
  1283.     case WM_COMMAND:
  1284.         switch (wParam)
  1285.         {
  1286.         case IDOK:
  1287.             if (state.graph_type != graph_type)
  1288.                 state.graph_type = graph_type;
  1289.  
  1290.             if (state.update_time != update_rate)
  1291.             {
  1292.                 state.update_time = update_rate;
  1293.                 SetProgramTimer(state.update_time - 9);
  1294.             }
  1295.             if (state.auto_rescale != auto_rescale)
  1296.                 state.auto_rescale = ! state.auto_rescale;
  1297.  
  1298.             if (state.on_top != keep_on_top)
  1299.                 state.on_top = ! state.on_top;
  1300.  
  1301.             if (state.on_caption != follow_window)
  1302.             {
  1303.                 state.on_caption = ! state.on_caption;
  1304.  
  1305.                 /*
  1306.                  * If on_caption is shut off put us
  1307.                  * back to normal.
  1308.                  */
  1309.                 if (! state.on_caption)
  1310.                     SetWindowPos(prog.hWnd, 1,
  1311.                              state.window_position.left,
  1312.                              state.window_position.top,
  1313.                              (state.window_position.right -
  1314.                               state.window_position.left),
  1315.                              (state.window_position.bottom -
  1316.                               state.window_position.top),
  1317.                              SWP_NOZORDER);
  1318.             }
  1319.  
  1320.             /*
  1321.              * Save the setup.
  1322.              */
  1323.             if (lParam == TRUE)
  1324.                 SetProgramSetup();
  1325.  
  1326.             EndDialog(hDlg, TRUE);
  1327.             break;
  1328.  
  1329.         case IDCANCEL:
  1330.             EndDialog(hDlg, TRUE);
  1331.             break;
  1332.  
  1333.         case IDSD_ON_CAPTION:
  1334.             follow_window = ! follow_window;
  1335.             CheckDlgButton(hDlg, IDSD_ON_CAPTION, follow_window);
  1336.             keep_on_top = TRUE;
  1337.             CheckDlgButton(hDlg, IDSD_ON_TOP, keep_on_top);
  1338.             break;
  1339.  
  1340.         case IDSD_ON_TOP:
  1341.             keep_on_top = ! keep_on_top;
  1342.             CheckDlgButton(hDlg, IDSD_ON_TOP, keep_on_top);
  1343.             follow_window = FALSE;
  1344.             CheckDlgButton(hDlg, IDSD_ON_CAPTION, follow_window);
  1345.             break;
  1346.  
  1347.         case IDSD_AUTO_RESCALE:
  1348.             auto_rescale = ! auto_rescale;
  1349.             CheckDlgButton(hDlg, IDSD_AUTO_RESCALE, auto_rescale);
  1350.             break;
  1351.  
  1352.         case IDSD_1SEC:
  1353.         case IDSD_2SEC:
  1354.         case IDSD_5SEC:
  1355.             update_rate = wParam;
  1356.             CheckRadioButton(hDlg, IDSD_1SEC, IDSD_5SEC, wParam);
  1357.             break;
  1358.  
  1359.         case IDSD_INV_QUEUE:
  1360.         case IDSD_QUEUE:
  1361.             graph_type = wParam;
  1362.             CheckRadioButton(hDlg, IDSD_QUEUE, IDSD_INV_QUEUE, wParam);
  1363.             break;
  1364.  
  1365.         case IDSD_SAVE_SETUP:
  1366.                         SendMessage(hDlg, WM_COMMAND, IDOK, TRUE);
  1367.                         break;
  1368.  
  1369.         default:
  1370.             return(FALSE);
  1371.         }
  1372.         break;
  1373.  
  1374.     default:
  1375.         return(FALSE);
  1376.     }
  1377.  
  1378.     return(TRUE);
  1379.  
  1380. } /* config_dialog */
  1381.  
  1382.  
  1383. /************************************************************************
  1384. * This handles all the messages for the ware dialog box.
  1385. *
  1386. * INPUT:  hDlg     = The dialog handle.
  1387. *      imessage = The message to look at.
  1388. *      wParam   = The parameter of the message.
  1389. *      lParam   = The parameter of the message.
  1390. *
  1391. * OUTPUT: NONE
  1392. */
  1393. #pragma argsused
  1394. BOOL FAR PASCAL WareDialog(HWND hDlg,   unsigned imessage,
  1395.                WORD wParam, LONG     lParam)
  1396. {
  1397.     switch (imessage)
  1398.     {
  1399.     case WM_INITDIALOG:
  1400.         break;
  1401.  
  1402.     case WM_ACTIVATEAPP:
  1403.         EndDialog(hDlg, TRUE);
  1404.         return(FALSE);
  1405.  
  1406.     case WM_COMMAND:
  1407.             EndDialog(hDlg, TRUE);
  1408.             break;
  1409.     default:
  1410.         return(FALSE);
  1411.     }
  1412.  
  1413.     return(TRUE);
  1414.  
  1415. } /* WareDialog */
  1416.  
  1417.  
  1418. /************************************************************************
  1419. * This handles all the messages for the about dialog box.
  1420. *
  1421. * INPUT:  hDlg     = The dialog handle.
  1422. *      imessage = The message to look at.
  1423. *      wParam   = The parameter of the message.
  1424. *      lParam   = The parameter of the message.
  1425. *
  1426. * OUTPUT: NONE
  1427. */
  1428. #pragma argsused
  1429. BOOL FAR PASCAL AboutDialog(HWND hDlg,   unsigned imessage,
  1430.                 WORD wParam, LONG     lParam)
  1431. {
  1432.     switch (imessage)
  1433.     {
  1434.     case WM_INITDIALOG:
  1435.         prog.halt = TRUE;
  1436.         SetDlgItemText(hDlg, IDAD_VERSION, (LPSTR) IDAD_VERSION_STR);
  1437.         SetDlgItemText(hDlg, IDAD_AUTHOR, (LPSTR) IDAD_AUTHOR_STR);
  1438.         break;
  1439.  
  1440.     case WM_ACTIVATEAPP:
  1441.         EndDialog(hDlg, TRUE);
  1442.         return(FALSE);
  1443.  
  1444.     case WM_DESTROY:
  1445.         prog.halt = FALSE;
  1446.         break;
  1447.  
  1448.     case WM_COMMAND:
  1449.         switch (wParam)
  1450.         {
  1451.         case IDOK:
  1452.             EndDialog(hDlg, TRUE);
  1453.             break;
  1454.  
  1455.         case IDAD_WARE:
  1456.             DialogBox(prog.hInstance, (LPSTR) "WARE_BOX", hDlg,
  1457.                   MakeProcInstance((FARPROC) WareDialog, prog.hInstance));
  1458.             break;
  1459.  
  1460.         default:
  1461.             return(FALSE);
  1462.         }
  1463.         break;
  1464.  
  1465.     default:
  1466.         return(FALSE);
  1467.     }
  1468.  
  1469.     return(TRUE);
  1470.  
  1471. } /* AboutDialog */
  1472.  
  1473.  
  1474. /************************************************************************
  1475. * This handles all the messages for the menu dialog box.  If the user
  1476. * clicks on another application we end this dialog.
  1477. *
  1478. * INPUT:  hDlg     = The dialog handle.
  1479. *      imessage = The message to look at.
  1480. *      wParam   = The parameter of the message.
  1481. *      lParam   = The parameter of the message.
  1482. *
  1483. * OUTPUT: NONE
  1484. */
  1485. #pragma argsused
  1486. BOOL FAR PASCAL MenuDialog(HWND hDlg,   unsigned imessage,
  1487.                WORD wParam, LONG     lParam)
  1488. {
  1489.     switch (imessage)
  1490.     {
  1491.     case WM_INITDIALOG:
  1492.         SetDlgPos(hDlg);
  1493.         if (IsIconic(prog.hWnd))
  1494.             SetDlgItemText(hDlg, IDMD_MINIMIZE, (LPSTR) "Maximize");
  1495.  
  1496.         prog.halt = TRUE;
  1497.         break;
  1498.  
  1499.     case WM_DESTROY:
  1500.         prog.halt = FALSE;
  1501.         break;
  1502.  
  1503.     case WM_ACTIVATEAPP:
  1504.         EndDialog(hDlg, TRUE);
  1505.         return(FALSE);
  1506.  
  1507.     case WM_COMMAND:
  1508.         switch (wParam)
  1509.         {
  1510.         case IDCANCEL:
  1511.             EndDialog(hDlg, TRUE);
  1512.             break;
  1513.  
  1514.         case IDMD_MINIMIZE:
  1515.             EndDialog(hDlg, TRUE);
  1516.             if (IsIconic(prog.hWnd))
  1517.             {
  1518.                 ShowWindow(prog.hWnd, SW_RESTORE);
  1519.                 SetDlgItemText(hDlg, IDMD_MINIMIZE, (LPSTR) "Maximize");
  1520.  
  1521.             }
  1522.             else
  1523.             {
  1524.                 ShowWindow(prog.hWnd, SW_MINIMIZE);
  1525.                 SetDlgItemText(hDlg, IDMD_MINIMIZE, (LPSTR) "Minimize");
  1526.  
  1527.             }
  1528.             break;
  1529.  
  1530.         case IDMD_SETUP:
  1531.             EndDialog(hDlg, TRUE);
  1532.             DialogBox(prog.hInstance,
  1533.                   (LPSTR) "SETUP_BOX",
  1534.                   prog.hWnd,
  1535.                   MakeProcInstance((FARPROC) SetupDialog,
  1536.                            prog.hInstance));
  1537.             break;
  1538.  
  1539.         case IDMD_ABOUT:
  1540.             EndDialog(hDlg, TRUE);
  1541.             DialogBox(prog.hInstance,
  1542.                   (LPSTR) "ABOUT_BOX",
  1543.                   prog.hWnd,
  1544.                   MakeProcInstance((FARPROC) AboutDialog, prog.hInstance));
  1545.             break;
  1546.  
  1547.         case IDMD_RESCALE:
  1548.             EndDialog(hDlg, TRUE);
  1549.             RescaleGraph();
  1550.             break;
  1551.  
  1552.         case IDMD_CLOSE:
  1553.             EndDialog(hDlg, TRUE);
  1554.             PostMessage(prog.hWnd, WM_CLOSE, 0, 0);
  1555.             break;
  1556.  
  1557.         default:
  1558.             return(FALSE);
  1559.         }
  1560.         break;
  1561.  
  1562.     default:
  1563.         return(FALSE);
  1564.     }
  1565.  
  1566.     return(TRUE);
  1567.  
  1568. } /* MenuDialog */
  1569.